/**
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. 
 */
import { CalendarWeekItem } from "../types/calendar";
import { DateObject, Period, MarkedDates, MarkStatus } from "../types/common";
import { DateModel } from "../types/date-model";
import { ActiveMonth, MonthViewItem, NameOfMonths } from "../types/month";
import { YearViewItem } from "../types/year";

export interface DateFormatInfo {
    value: string;
    format: string;
}

export interface UseDateFormat {
    formatDate: (date: DateObject, dateFormat: string, monthLabels: NameOfMonths) => string;

    getDateValue: (dateStr: string, dateFormat: string, delimeters: string[] | null) => DateFormatInfo[];

    preZero: (val: number) => string;

    remove: (format: string, delStr: string) => string;
}

export interface UseDate {

    emptyDate: () => DateObject;

    getDate: (date: DateObject) => Date;

    getDate2: (date: DateObject) => Date;

    getDayNumber: (date: DateObject) => number;

    getWeekdayIndex: (wd: string) => number;

    getTimeInMilliseconds: (date: DateObject) => number;

    getEpocTime: (date: DateObject) => number;

    getNearDate: (now: DateObject, min: DateObject, max: DateObject) => DateObject;

    getToday(): DateObject;
}

export interface UseNumber {

    getDayNumber: (date: DateObject) => number;

    getNumberByValue: (df: DateFormatInfo) => number;

    getMonthNumberByMonthName: (df: DateFormatInfo, monthLabels: NameOfMonths) => number;

    getWeekNumber: (date: DateObject) => number;
}

export interface UseNormalizeDate {
    normalizeDate: (dateString: string, useValueFormat: boolean) => DateObject;
}

export interface UseCompare {
    isDateEarlier: (firstDate: DateObject, secondDate: DateObject) => boolean;

    equal: (firstDate: DateObject, secondDate: DateObject) => boolean;

    inPeriod: (date: DateObject, period: Period | null) => boolean;

    isPoint: (period: Period, date: DateObject) => boolean;

    equalOrEarlier: (firstDate: DateObject, secondDate: DateObject) => boolean;

    isInitializedDate: (date: DateObject) => boolean;

    isInitializedMonth: (date: DateObject) => boolean;

    isInitializedYear: (date: DateObject) => boolean;

    isMonthDisabledByDisableSince: (date: DateObject, disableSince: DateObject) => boolean;

    isMonthDisabledByDisableUntil: (date: DateObject, disableUntil: DateObject) => boolean;

}

export interface UseMonth {
    parseDefaultMonth: (monthString: string) => ActiveMonth;

    daysInMonth: (month: number, year: number) => number;

    daysInPreMonth: (month: number, year: number) => number;

    generateMonths: (
        nameOfMonths: string[],
        selectedMonth: DateObject,
        disableSince: DateObject,
        disableUntil: DateObject
    ) => MonthViewItem[][];

    getNextMonth: (month: number, year: number) => DateObject;

    getPreviousMonth: (month: number, year: number) => DateObject;
}

export interface UseMark {
    isMarkedDate: (date: DateObject, markedDates: MarkedDates[], markWeekends: MarkStatus) => MarkStatus;

    isHighlightedDate: (date: DateObject, sunHighlight: boolean, satHighlight: boolean, highlightDates: DateObject[]) => boolean;
}

export interface UseWeek {
    getNowWeekTime: (date: Date) => Period;
}

export interface UseDisableTime {
    disabledHours: (min: DateObject, max: DateObject, currentDate: DateObject) => number[];

    disabledMinutes: (min: DateObject, max: DateObject, currentDate: DateObject) => number[];

    disabledSeconds: (min: DateObject, max: DateObject, _hour: number, _minute: number, currentDate: DateObject) => number[];
}

export interface UseDateModel {

    getDateModel: (
        date: DateObject, period: Period, dateFormat: string,
        nameOfMonths: NameOfMonths, rangeDelimiter: string, returnFormat: string, dateStr: string
    ) => DateModel;

    getFormattedDate: (model: DateModel) => string | undefined;
}

export interface UseDisableDate {
    isDisabledDate: (date: DateObject) => boolean;
}

export interface UseEvent {
    getKeyCodeFromEvent: (event: KeyboardEvent) => number;
}

export interface UseDisableMonth {
    isMonthDisabledByDisableUntil: (date: DateObject, disableUntil: DateObject) => boolean;

    isMonthDisabledByDisableSince: (date: DateObject, disableSince: DateObject) => boolean;
}

export interface UseYear {
    generateYears: (
        input: number,
        selectedMonth: DateObject,
        min: number,
        max: number,
        disableSince: DateObject,
        disableUntil: DateObject
    ) => YearViewItem[][];
}

export interface UseCalendar {
    generateCalendar: (
        month: number,
        year: number,
        firstDayOfWeek: string,
        markedDates: MarkedDates[],
        markWeekends: MarkStatus,
        highlightDates: DateObject[],
        highlightSaturday: boolean,
        highlightSunday: boolean,
        showWeekNumbers: boolean
    ) => CalendarWeekItem[];
}
